package jm.nj.demo16main.demoProxy;

import org.junit.Test;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/*
* 动态代理的综合案例:模拟Collections中的unmodifiableList方法
*
* 目的:
 * 	自己定义一个方法proxyList
 * 	方法的参数传递List集合,方法内部对List集合进行代理,把代理后的List集合返回
 * 		List集合被代理之后,执行size,get,没有对集合进行修改,代理人允许执行
 * 		List集合被代理之后,执行add,remove,set,对集合进行修改,代理人不允许执行,抛出异常
 *
 *
 * 实现步骤:
 * 1.定义一个方法proxylist,方法的参数传递List集合,把代理后的list返回
 * 2.proxyLIst方法内部实现动态代理
 *              java.lang.reflect.Proxy:有实现动态代理的方法
 *              Proxy 提供用于创建动态代理类和实例的静态方法，它还是由这些方法创建的所有动态代理类的超类。
 *              static Object newProxyInstance(ClassLoader loader  , Class<?> []   interfaces ,InvocationHandler  h)
 *                          返回一个指定接口的代理类实例，该接口可以将方法调用指派到指定的调用处理程序。
 *                          方法的参数:
 *                                  ClassLoader:定义代理类的加载器,获取加载本类的应用类加载器,把本类加载到内存中
 *                                  class<?> []  interfaces:ArrayList集合的父类接口的Class类文件对象(List,Collection)
 *                                      InvocationHandler接口:创建InvocationHandler接口实现类对象,重写接口中的方法invoke
 *                                  对集合的方法进行判断,size,get允许执行;add,remove,set不允许执行,抛出异常
 *方法的返回值:
 * 				Object:被代理的对象
 *
 *
 *
* */
@SuppressWarnings("all")
public class Demo02Proxy {
    //测试自定义代理方法
    @Test
    public void demo01(){
        List<String> list = new ArrayList<String>();
        list.add("aaa");
        list.add("bbb");
        //调用
        System.out.println(list.getClass()/*.getInterfaces()*/);
        System.out.println(list.getClass().getInterfaces());
        list = proxyList(list);
        System.out.println(list.getClass()/*.getInterfaces()*/);
        System.out.println(list.getClass().getInterfaces());
        list.size();
    }
    // 1.定义一个方法proxyList,方法的参数传递List集合,把代理后的List集合返回
    private List<String> proxyList(List<String> list) {
//2.proxyList方法内部实现动态代理
        List<String> proxyList = (List<String>) Proxy.newProxyInstance(Demo02Proxy.class.getClassLoader(), list.getClass().getInterfaces(),new InvocationHandlerImpl(list));

        return proxyList;
    }



}
